package com.atguigu.yygh.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.common.utils.HttpRequestHelper;
import com.atguigu.yygh.hosp.repository.ScheduleRepository;
import com.atguigu.yygh.hosp.result.Result;
import com.atguigu.yygh.hosp.service.ScheduleService;
import com.atguigu.yygh.model.hosp.Schedule;
import com.atguigu.yygh.vo.hosp.BookingScheduleRuleVo;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class ScheduleServiceImpl implements ScheduleService {

    @Autowired
    ScheduleRepository scheduleRepository;

    @Autowired
    MongoTemplate mongoTemplate;


    @Override
    public Result saveSchedule(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> stringObjectMap = HttpRequestHelper.switchMap(parameterMap);

        String jsonString = JSONObject.toJSONString(stringObjectMap);
        Schedule schedule = JSONObject.parseObject(jsonString, Schedule.class);

        String hoscode = schedule.getHoscode();
        if (hoscode.isEmpty()){
            throw new YyghException(20001,"hoscode为空");
        }
        String depcode = schedule.getDepcode();
        if (depcode.isEmpty()){
            throw new YyghException(20001,"depcode为空");
        }

        String hosScheduleId = schedule.getHosScheduleId();
        if (hosScheduleId.isEmpty()){
            throw new YyghException(20001,"hosScheduleId为空");
        }


        Schedule schedules = scheduleRepository.getSchedulesByHoscodeAndDepcodeAndHosScheduleId(hoscode, depcode,hosScheduleId);
        if (schedules==null){
            schedule.setCreateTime(new Date());
            schedule.setUpdateTime(new Date());
            scheduleRepository.save(schedule);
        }else {
            schedule.setUpdateTime(new Date());
            scheduleRepository.save(schedule);
        }


        return Result.ok();
    }

    @Override
    public Result getScheduleList(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> stringObjectMap = HttpRequestHelper.switchMap(parameterMap);
        String hoscode = stringObjectMap.get("hoscode").toString();
        if (hoscode==null){
            throw new YyghException(20001,"异常");
        }

        String depcode = stringObjectMap.get("depcode").toString();
        if (depcode==null){
            throw new YyghException(20001,"异常");
        }
        int pageNum = Integer.parseInt((String) stringObjectMap.get("page"))-1;
        int pageSize = Integer.parseInt((String) stringObjectMap.get("limit"));



        Schedule schedule = new Schedule();
        schedule.setHoscode(hoscode);
        schedule.setDepcode(depcode);
        ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreCase(true).withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
        Example<Schedule> ex = Example.of(schedule,matcher);

        Sort sort = Sort.by(Sort.Direction.DESC,"createTime");
        Pageable pageAble = PageRequest.of(pageNum,pageSize,sort);
        Page<Schedule> schedules = scheduleRepository.findAll(ex, pageAble);
        return Result.ok(schedules);
    }

    @Override
    public Result removeSchedule(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> objectMap = HttpRequestHelper.switchMap(parameterMap);
        String hoscode = objectMap.get("hoscode").toString();
        if (hoscode==null){
            throw new YyghException(20001,"异常");
        }
        String hosScheduleId = objectMap.get("hosScheduleId").toString();
        if (hosScheduleId==null){
            throw new YyghException(20001,"异常");
        }
        scheduleRepository.deleteScheduleByHoscodeAndHosScheduleId(hoscode,hosScheduleId);

        return Result.ok();
    }

    @Override
    public Map<String,Object> getScheduleRule(String page, String limit, String hoscode, String depcode) {
        HashMap<String, Object> hashMap = new HashMap<>();

        // 查询条件
        Criteria criteria = Criteria.where("hoscode").is(hoscode).and("depcode").is(depcode);

        // 聚合分组 --> 条件
        Aggregation aggration = Aggregation.newAggregation(
            Aggregation.match(criteria),
                Aggregation.group("workDate")
                        .first("workDate").as("workDate")
                        .count().as("docCount")
                        .sum("reservedNumber").as("reservedNumber")
                        .sum("availableNumber").as("availableNumber")
                        .first("status").as("status"),
                Aggregation.sort(Sort.Direction.ASC,"workDate"),
                Aggregation.skip(Integer.parseInt(page)-1),
                Aggregation.limit(Long.parseLong(limit))
        );


        // 执行聚合任务
        AggregationResults<BookingScheduleRuleVo> bookingScheduleRuleVos = mongoTemplate.aggregate(aggration, Schedule.class, BookingScheduleRuleVo.class);
        List<BookingScheduleRuleVo> bookingScheduleRuleVoList = bookingScheduleRuleVos.getMappedResults();

        // 遍历，为内的每个对象 set --> WorkDateMD And --> DayOfWeek
        bookingScheduleRuleVoList.forEach(bookingScheduleRuleVo -> {
            bookingScheduleRuleVo.setWorkDateMd(bookingScheduleRuleVo.getWorkDate());
            getDayOfWeek(bookingScheduleRuleVo);
        });

        hashMap.put("bookingScheduleRuleList",bookingScheduleRuleVoList);

        Long total = scheduleRepository.countAllByHoscodeAndDepcode(hoscode, depcode);

        // 总排版分组的数量
        hashMap.put("total",total);

        // 获取当前第列表第一天的排版信息，显示在界面上。
        List<Schedule> scheduleList = scheduleRepository.getSchedulesByHoscodeAndDepcodeAndWorkDate(hoscode, depcode, bookingScheduleRuleVoList.get(0).getWorkDate());

        hashMap.put("scheduleList",scheduleList);

        hashMap.put("baseMap",null);

        return hashMap;
    }

    @Override
    public List<Schedule> getScheduleDetail(String hoscode, String depcode, Date workDate) {
        List<Schedule> scheduleList = scheduleRepository.getSchedulesByHoscodeAndDepcodeAndWorkDate(hoscode, depcode, workDate);
        return scheduleList;
    }

    /**
     * 通过对象的 WorkDate 为 DayOfWeek 进行赋值
     * @param bookingScheduleRuleVo
     */
    private static void getDayOfWeek(BookingScheduleRuleVo bookingScheduleRuleVo) {
        DateTime dateTime = new DateTime(bookingScheduleRuleVo.getWorkDate());
        DateTime.Property ofWeek = dateTime.dayOfWeek();

        switch (ofWeek.get() + 1){
            case 1:
                bookingScheduleRuleVo.setDayOfWeek("周一");
                break;
            case 2:
                bookingScheduleRuleVo.setDayOfWeek("周二");
                break;
            case 3:
                bookingScheduleRuleVo.setDayOfWeek("周三");
                break;
            case 4:
                bookingScheduleRuleVo.setDayOfWeek("周四");
                break;
            case 5:
                bookingScheduleRuleVo.setDayOfWeek("周五");
                break;
            case 6:
                bookingScheduleRuleVo.setDayOfWeek("周六");
                break;
            case 7:
                bookingScheduleRuleVo.setDayOfWeek("周日");
                break;
        }
    }
}
